/**
 * @file:main.c
 * @brief:分层状态机用例
 * @author:liaowx
 * @date:2019.08.02
 */
#include <stdio.h>
#include <malloc.h>

#include "air_conditioning.h"

struct air_conditioning ON_OFF;
struct air_conditioning ON_ON;
struct air_conditioning REFRIGERATION;
struct air_conditioning AUTOMATIC;
struct air_conditioning HEATING;
struct air_conditioning TEMPRATURE_CONTROL;

struct air_conditioning *state_off_handler(struct air_conditioning *cur_state,
                                enum EVENT event)
{
    if (event == ENTRY) {
        printf("\tEnter ON_OFF\n");
    } else if (event == EXIT) {
        printf("\tExit ON_OFF\n");
    } else if (event == OPEN) {
        cur_state = tran(cur_state, &ON_ON);
        return cur_state;
    }

    return cur_state;
}

struct air_conditioning *state_on_handler(struct air_conditioning *cur_state,
                            enum EVENT event)
{
    if (event == ENTRY) {
        printf("\tEnter ON_ON\n");
    } else if (event == EXIT) {
        printf("\tExit ON_ON\n");
    } else if (event == INIT) {
        cur_state = tran(cur_state, &AUTOMATIC);
    } else if (event == CLOSE) {
        cur_state = tran(cur_state, &ON_OFF);
        return cur_state;
    }

    return cur_state;
}

struct air_conditioning *state_automatic_handler(struct air_conditioning *cur_state,
                                    enum EVENT event)
{
    if (event == ENTRY) {
        printf("\tEnter AUTOMATIC\n");
    } else if (event == EXIT) {
        printf("\tExit AUTOMATIC\n");
    } else if (event == MAKE_COLD) {
        cur_state = tran(cur_state, &REFRIGERATION);
        return cur_state;
    } else if (event == MAKE_HOT) {
        cur_state = tran(cur_state, &HEATING);
        return cur_state;
    } else if (event == CLOSE) {
        cur_state = tran(cur_state, &ON_OFF);
        return cur_state;
    }

    return cur_state;
}

struct air_conditioning *state_temprature_control_handler(struct air_conditioning *cur_state,
                                                enum EVENT event)
{
    if (event == ENTRY) {
        printf("\tEnter TEMPRATURE_CONTROL\n");
    } else if (event == EXIT) {
        printf("\tExit TEMPRATURE_CONTROL\n");
    } else if (event == CLOSE) {
        cur_state = tran(cur_state, &ON_OFF);
        return cur_state;
    }

    return cur_state;
}

struct air_conditioning *state_refrigeration_handler(struct air_conditioning *cur_state,
                                        enum EVENT event)
{
    if (event == ENTRY) {
        printf("\tEnter REFRIGERATION\n");
    } else if (event == MAKE_HOT) {
        cur_state = tran(cur_state, &HEATING);
        return cur_state;
    } else if (event == CLOSE) {
        cur_state = tran(cur_state, &ON_OFF);
        return cur_state;
    } else if (event == EXIT) {
        printf("\tExit REFRIGERATION\n");
    }

    return cur_state;
}

struct air_conditioning *state_heating_handler(struct air_conditioning *cur_state,
                                    enum EVENT event)
{
    if (event == ENTRY) {
        printf("\tEnter HEATING\n");
    } else if (event == CLOSE) {
        cur_state = tran(cur_state, &ON_OFF);
        return cur_state;
    } else if (event == MAKE_COLD) {
        cur_state = tran(cur_state, &REFRIGERATION);
        return cur_state;
    } else if (event == EXIT) {
        printf("\tExit HEATING\n");
    }

    return cur_state;
}

int main()
{
    struct air_conditioning *cur_state = (struct air_conditioning *)malloc
                                            (sizeof(struct air_conditioning));

    state_init(&ON_OFF, "OFF", 24, 3, state_off_handler, NULL);
    state_init(&ON_ON, "ON", 24, 3, state_on_handler, NULL);
    state_init(&AUTOMATIC, "AUTOMATIC", 24, 3, state_automatic_handler,
                                                        &ON_ON);
    state_init(&TEMPRATURE_CONTROL, "TEMPRATURE_CONTROL", 24, 3,
                            state_temprature_control_handler, &ON_ON);
    state_init(&REFRIGERATION, "REFRIGERATION", 24, 3,
                            state_refrigeration_handler, &TEMPRATURE_CONTROL);
    state_init(&HEATING, "HEATING", 24, 3,
                            state_heating_handler, &TEMPRATURE_CONTROL);

    cur_state = state_creat(cur_state, &ON_OFF);
    cur_state = state_run(cur_state, OPEN);
    cur_state = state_run(cur_state, MAKE_COLD);
    cur_state = state_run(cur_state, MAKE_HOT);
    cur_state = state_run(cur_state, CLOSE);
    return 0;
}